﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

using King.Extensions;
using King.Reflection;
using King.Antlr3;

using Antlr.Runtime;
using Antlr.Runtime.Tree;

namespace King.Language {

    public abstract class Ast {

        private Ast m_parent;
        private NillableToken? m_token;
        private List<Ast> m_children;
        private IEnumerable<Ast> m__children;

        protected Ast(IEnumerable<Ast> children = null, NillableToken? token = null) {
            m_token = token;
            m__children = children;
        }

        public Ast Parent {
            get { return m_parent; }
        }
        public IEnumerable<Ast> Children() {

            if (m__children != null) {
                m_children = m__children.WhereNotDefault().ToList();
                foreach (var child in m_children)
                    child.m_parent = this;
            }

            return m_children ?? Enumerable.Empty<Ast>();
        }
        public NillableToken Token {
            get { return (NillableToken)m_token; }
        }

        public override string ToString() {
            string channelStr = "";
            string txt = Token.Text;
            if (txt != null) {
                txt = Regex.Replace(txt, "\n", "\\\\n");
                txt = Regex.Replace(txt, "\r", "\\\\r");
                txt = Regex.Replace(txt, "\t", "\\\\t");
            } else {
                txt = "<no text>";
            }
            return "[" + txt + ", <" + GetType().Name + ">" + channelStr + ", " + 
                Token.Line + ":" + Token.Column + "@" + Token.Position + "]";
        }
    }
}
